package com.ra.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.ra.config.security.CustomFilter;
import com.ra.exception.BizException;
import com.ra.mapper.RoleResourceMapper;
import com.ra.pojo.Menu;
import com.ra.pojo.Resource;
import com.ra.mapper.ResourceMapper;

import com.ra.pojo.RoleResource;
import com.ra.pojo.dto.ConditionDTO;
import com.ra.pojo.dto.LabelOptionDTO;
import com.ra.pojo.dto.ResourceDTO;
import com.ra.pojo.dto.ResourceDTOByAdmin;
import com.ra.service.IResourceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ra.utils.BeanCopyUtil;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;
import static com.ra.constant.CommonConstant.*;
import static java.util.stream.Collectors.groupingByConcurrent;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 今晚几点睡_Ada
 * @since 2023-03-09
 */
@Service
public class ResourceServiceImpl extends ServiceImpl<ResourceMapper, Resource> implements IResourceService {


    @Autowired
    private ResourceMapper resourceMapper;
    @Autowired
    private RoleResourceMapper roleResourceMapper;
    @Autowired
    private CustomFilter customFilter;


    @Override
    public List<ResourceDTO> listResource(ConditionDTO conditionDTO) {
        List<Resource> resources = resourceMapper
                .selectList(new LambdaQueryWrapper<Resource>()
                        .like(StringUtils.isNotBlank(conditionDTO.getKeywords()),
                                Resource::getResourceName, conditionDTO.getKeywords()));
        List<Resource> parent = resources.stream().filter(item -> Objects.isNull(item.getParentId())).collect(Collectors.toList());
        Map<Integer, List<Resource>> children = resources.stream().filter(item -> Objects.nonNull(item.getParentId())).collect(Collectors.groupingBy(Resource::getParentId));
        List<ResourceDTO> collect = parent.stream().map(item -> {
            ResourceDTO resourceDTO = BeanCopyUtil.copyObject(item, ResourceDTO.class);
            resourceDTO.setChildren(BeanCopyUtil.copyList(children.get(item.getId()), ResourceDTO.class));
            children.remove(item.getId());
            return resourceDTO;
        }).collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(children)) {
            List<Resource> childrenList = new ArrayList<>();
            children.values().forEach(childrenList::addAll);

            List<ResourceDTO> childrenDTOs = childrenList.stream()
                    .map(item -> BeanCopyUtil.copyObject(item, ResourceDTO.class))
                    .collect(Collectors.toList());
            collect.addAll(childrenDTOs);
        }
        return collect;
    }

    @Override
    public void saveOrUpdateResource(ResourceDTOByAdmin resource) {
        saveOrUpdate(BeanCopyUtil.copyObject(resource, Resource.class));
        customFilter.clearDataSource();
    }

    @Override
    @SneakyThrows
    public void delResource(Integer id) {
         Integer count = roleResourceMapper.selectCount(new LambdaQueryWrapper<RoleResource>().eq(RoleResource::getResourceId, id));
        System.out.println("count = " + count);
        if(count>0){
             throw new BizException("资源下存在角色");
         }
         //没有角色 则看他是不是父菜单 父菜单则删除所有子菜单
        //子菜单
         List<Resource> submenu = resourceMapper.selectList(new LambdaQueryWrapper<Resource>().select(Resource::getId).eq(Resource::getParentId, id));
         List<Integer> submenuList = submenu.stream().map(Resource::getId).collect(Collectors.toList());
         submenuList.add(id);
         resourceMapper.deleteBatchIds(submenuList);
    }

    @Override
    public List<LabelOptionDTO> queryRoleResources() {
        List<Resource> resources = resourceMapper.selectList(new LambdaQueryWrapper<Resource>()
                .select(Resource::getId, Resource::getResourceName,
                        Resource::getParentId).eq(Resource::getIsAnonymous,ZERO));
      //  System.out.println("resources = " + resources);
         List<Resource> parents = resources.stream()
                .filter(item -> Objects.isNull(item.getParentId()))
                .collect(Collectors.toList());
      Map<Integer, List<Resource>> childrens= resources.stream()
                .filter(item -> Objects.nonNull(item.getParentId()))
                .collect(Collectors.groupingBy(Resource::getParentId));

         List<LabelOptionDTO> roleResources = parents.stream().map(item -> {
            List<LabelOptionDTO> list = new ArrayList<>();
            List<Resource> children = childrens.get(item.getId());
            if (CollectionUtils.isNotEmpty(children)) {
                list = children.stream()
                        .map(resource -> LabelOptionDTO.builder()
                                .id(resource.getId())
                                .name(resource.getResourceName())
                                .build())
                        .collect(Collectors.toList());
            }
            return LabelOptionDTO.builder()
                    .id(item.getId())
                    .name(item.getResourceName())
                    .subItem(list)
                    .build();
        }).collect(Collectors.toList());


        return roleResources;
    }
}
